package com.the8thfold.anton.services

import org.apache.tools.ant.Project
import org.apache.tools.ant.DefaultLogger
import org.apache.tools.ant.ProjectHelper
import org.apache.tools.ant.BuildException
import com.the8thfold.anton.ant.AntScript
import org.apache.tools.ant.Target
import com.the8thfold.anton.ant.AntJobRunResults
import com.the8thfold.anton.utils.ConfigurationUtils
import com.the8thfold.anton.ant.AntJob
import grails.plugin.multitenant.core.util.TenantUtils
import com.the8thfold.anton.ant.AntJobStatus

class ScriptRunnerService {

    def notificationsService

    static transactional = true

    public static runningProjectsMap = [:]

    def getRunningAntProject(String resultId) {
        runningProjectsMap.get(resultId)
    }

    def runScript(AntScript antScript) {

        File buildFile = new File("C:/work/workspace/anton/build.xml");
        Project antProject = new Project();
        antProject.setUserProperty("ant.file", buildFile.getAbsolutePath());
        ProjectHelper helper = ProjectHelper.getProjectHelper();


        antProject.getDefaultTarget();
        antProject.getDescription();
        antProject.getTaskDefinitions();
        antProject.getProperties()
        antProject.getReferences()
        antProject.getUserProperties()



        DefaultLogger consoleLogger = new DefaultLogger();
        consoleLogger.setErrorPrintStream(System.err);
        consoleLogger.setOutputPrintStream(System.out);
        consoleLogger.setMessageOutputLevel(Project.MSG_INFO);
        antProject.addBuildListener(consoleLogger);

        try {
            antProject.fireBuildStarted();
            antProject.init();
            antProject.addReference("ant.projectHelper", helper);
            helper.parse(antProject, buildFile);

            def targets = antProject.getTargets();
            targets.each { name, target ->
                Target t = target;
                t.description
            }

            antProject.executeTarget(antProject.getDefaultTarget());
            antProject.fireBuildFinished(null);
        } catch (BuildException e) {
            antProject.fireBuildFinished(e);
        }


    }

    def runJob(AntJobRunResults results) {

        runAsync  {
            TenantUtils.doWithTenant(1) {

                File buildFile = new File(results.job.script.scriptFilePath)
                Project antProject = new Project()
                try {
                    antProject.setUserProperty("ant.file", buildFile.getAbsolutePath())
                    ProjectHelper helper = ProjectHelper.getProjectHelper()
                    antProject.getDefaultTarget()
                    antProject.getDescription()
                    antProject.getTaskDefinitions()
                    antProject.getProperties()
                    antProject.getReferences()
                    antProject.getUserProperties()

                    File logFile = new File(ConfigurationUtils.getResultFolderName(results), "resultLog.log")
                    File errorLogFile = new File(ConfigurationUtils.getResultFolderName(results), "resultErrorLog.log")

                    DefaultLogger consoleLogger = new DefaultLogger()
                    consoleLogger.setErrorPrintStream(new PrintStream(errorLogFile))
                    consoleLogger.setOutputPrintStream(new PrintStream(logFile))
                    consoleLogger.setMessageOutputLevel(Project.MSG_VERBOSE)
                    antProject.addBuildListener(consoleLogger)

                    results.runLog = logFile.absolutePath
                    results.runErrorLog = errorLogFile.absolutePath
                    results.save(flush: true, failOnError: true)

                    runningProjectsMap.put(results.runResultsId, antProject)
                    antProject.fireBuildStarted();
                    antProject.init();
                    antProject.addReference("ant.projectHelper", helper);
                    helper.parse(antProject, buildFile);

                    AntJob job = AntJob.findByJobId(results.job.jobId)

                    def targets = job.targets.sort { it.ordinal};
                    targets.each {
                        antProject.executeTarget(it.name);
                    }

                    antProject.fireBuildFinished(null);
                } catch (BuildException e) {
                    antProject.fireBuildFinished(e);
                } finally {
                    runningProjectsMap.remove(results.runResultsId)
                    results.status = AntJobStatus.COMPLETE ;
                    results.save(flush: true, failOnError: true) ;

                    notificationsService.notifyRunResult(results);
                }
            }

        };

    }
}
